package com.training.utils;

import javax.crypto.SecretKey;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class RSAUtil {
    
    private static final String ALGORITHM = "RSA";
    private static final String TRANSFORMATION = "RSA/ECB/PKCS1Padding";

    /**
     * 使用RSA私钥解密数据
     * @param encryptedData 被加密的数据（Base64编码）
     * @param privateKey RSA私钥
     * @return 解密后的原始数据
     * @throws Exception 解密异常
     */
    public static byte[] decryptData(String encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        return cipher.doFinal(decodedData);
    }
    
    /**
     * 使用私钥字符串解密服务器返回的RSA加密过的AES密钥字符串
     * @param encryptedAESKey 经过RSA加密的AES密钥（Base64编码的字符串）
     * @param privateKeyStr 私钥字符串（Base64编码）
     * @return 解密后的AES密钥字符串
     * @throws Exception 解密异常
     */
    public static String decryptAESKey(String encryptedAESKey, String privateKeyStr) throws Exception {
        // 从私钥字符串创建私钥对象
        PrivateKey privateKey = createPrivateKey(privateKeyStr);
        
        // 解密数据
        byte[] decryptedData = decryptData(encryptedAESKey, privateKey);
        
        // 将解密后的字节数组转换为字符串
        return new String(decryptedData);
    }

    /**
     * 从Base64编码字符串创建私钥对象
     * @param privateKeyStr Base64编码的私钥字符串
     * @return PrivateKey对象
     * @throws Exception 创建私钥异常
     */
    public static PrivateKey createPrivateKey(String privateKeyStr) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(spec);
    }
}